package com.itheima.proxy_review.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @program: design
 * @description: jdk代理
 * 1:需要是接口
 * 2:需要转成接口类型才能搞定呀
 * 3:需要有实例对象传入进行执行方法
 * 4:需要新建 代理对象
 * 5:需要注意接口列表和classloader
 * @author: zhanghz001
 * @create: 2021-02-26 22:02
 **/
public class JdkProxyTest {
    public static void main2(String[] args) {
        Service1 service1 = new Service1Impl();
        Service1 o = (Service1) Proxy.newProxyInstance(
                Service1.class.getClassLoader(),
                Service1Impl.class.getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("前面的操作");
                        Object invoke = method.invoke(service1, args);
                        System.out.println("后面的操作");
                        return invoke;
                    }
                });
        o.pay("hahaha");
    }
    
    public static void main1(String[] args) {
        //需要有一个实例对象
        Service1 service1 = new Service1Impl();
        //需要有一个代理对象,可以使用新类来代替
        InvocationHandler proxy = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getName().equals("pay")) {
                    System.out.println("pay 方法执行");
                }
                return method.invoke(service1, args);
            }
        };
        //通过proxy的方法 newProxyInstance实现
        Service1 instance = (Service1) Proxy
                .newProxyInstance(service1.getClass().getClassLoader()
                        , Service1Impl.class.getInterfaces(),
                        proxy);
        //调用方法
        instance.pay("陈尧");
    }
    
    //final修饰的还是可以调用的,这个和cglib不一样
    public static void main(String[] args) {
        String s1 = "";
        CharSequence o = (CharSequence) Proxy.newProxyInstance(
                String.class.getClassLoader()
                , String.class.getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if (method.getName().equals("toString")) {
                            System.out.println("toString来了");
                        }
                        return method.invoke(s1, args);
                    }
                });
        o.toString();
    }
}
